﻿using System.Reflection;
using Autofac;
using BlogSystem.Common.Util;
using Microsoft.AspNetCore.Mvc;
using Module = Autofac.Module;

namespace BlogSystem.Common.Config.DI;

/// <summary>
/// Autofac 中用于配置依赖注入(DI)的方法
/// </summary>
public class AutofacRegisterModule  : Module
{
    
    //重写了 Autofac.Module 类中的 Load 方法
    protected override void Load(ContainerBuilder builder)
    {
        //GetExportedTypes() 获取了程序集中所有的公共类型，
        //并筛选出那些继承自 ControllerBase 的类型
        //获取所有控制器类型并使用属性注入
        Type[] controllersTypeAssembly = typeof(Program).Assembly.GetExportedTypes()
            .Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
        
        //builder 对象注册了之前筛选出来的控制器类型
        //调用 PropertiesAutowired 方法并传递了一个 AutowiredPropertySelector 实例作为参数，这是一个自定义的属性选择器，用于在注册类型时启用属性注入。
        builder.RegisterTypes(controllersTypeAssembly)
            .PropertiesAutowired(new AutowiredPropertySelector());
        
        // Autofac 的 BatchRegistrationExtensions 类中的 BatchAutowired 方法
        //它批量自动注册了 IocManager 类所在程序集中的所有类型，这意味着会自动注册程序集中的所有服务和其对应的实现类。
        // builder.BatchAutowired(typeof(IocManager).Assembly);
        
        //业务逻辑层注入
        var serviceImpl = 
            AssemblyHelper.GetAssemblyByNamespace("BlogSystem.Service.Impl");
        builder.BatchAutowired(serviceImpl);
        
        //仓储层注入
        var repositoryImpl =  
            AssemblyHelper.GetAssemblyByNamespace("BlogSystem.Data.Repository.RepositoryImpl");
             // 批量注入装配
        builder.BatchAutowired(repositoryImpl);
        
        //当前程序集注入
        builder.BatchAutowired(Assembly.GetCallingAssembly());
    }
}